package com.github.anastr.speedviewlib;

import com.github.anastr.speedviewlib.util.AttrSetUtils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

public abstract class LinearGauge extends Gauge {

    private Paint paint = new Paint();
    /**
     * to draw part of bitmap
     */
    private RectFloat rect = new RectFloat();
    private PixelMap foregroundBitmap;

    /**
     * horizontal or vertical direction
     */
    private Orientation orientation = Orientation.HORIZONTAL;


    public LinearGauge(Context context) {
        this(context, null);
    }

    public LinearGauge(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public LinearGauge(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        paint.setAntiAlias(true);
        initAttributeSet(context, attrSet);
    }

    /**
     * update background and foreground bitmap,
     * this method called when change size, color, orientation...
     * <p>
     * must call {@link #createBackgroundBitmapCanvas()} and
     * {@link #createForegroundBitmapCanvas()} inside this method.
     * </p>
     */
    protected abstract void updateFrontAndBackBitmaps();

    private void initAttributeSet(Context context, AttrSet attrs) {
        if (attrs == null)
            return;
        int orientation = AttrSetUtils.getInt(attrs, "sv_orientation", -1);
        if (orientation != -1)
            setOrientation(Orientation.values()[orientation]);
    }

    @Override
    protected void onSizeChange(int w, int h, int oldW, int oldH) {
        super.onSizeChange(w, h, oldW, oldH);
        updateBackgroundBitmap();
    }

    @Override
    protected void updateBackgroundBitmap() {
        updateFrontAndBackBitmaps();
    }

    protected final Canvas createForegroundBitmapCanvas() {
        if (getWidthPa() == 0 || getHeightPa() == 0)
            return new Canvas();
        PixelMap.InitializationOptions options = new PixelMap.InitializationOptions();
        options.editable = true;
        Size size = new Size(getWidthPa(), getHeightPa());
        options.size = size;
        options.pixelFormat = PixelFormat.ARGB_8888;
        foregroundBitmap = PixelMap.create(options);
        Canvas canvas = new Canvas(new Texture(foregroundBitmap));
        return canvas;
    }

    @Override
    public void onDrawComponent(Component component, Canvas canvas) {
        super.onDrawComponent(component, canvas);
        if (orientation == Orientation.HORIZONTAL)
            rect = new RectFloat(0, 0
                    , (int)(getWidthPa() * getOffsetSpeed()), getHeightPa());
        else
            rect = new RectFloat(0, getHeightPa() - (int)(getHeightPa() * getOffsetSpeed())
                    , getWidthPa(), getHeightPa());

        canvas.translate(getCustomPadding(), getCustomPadding());
        canvas.drawPixelMapHolderRect(new PixelMapHolder(foregroundBitmap), rect, rect, paint);
        canvas.translate(-getCustomPadding(), -getCustomPadding());

        drawSpeedUnitText(canvas);
    }


    public Orientation getOrientation() {
        return orientation;
    }

    /**
     * change fill orientation,
     * this will change view width and height.
     * @param orientation new orientation.
     */
    public void setOrientation(Orientation orientation) {
        this.orientation = orientation;
        if (!isAttachedToWindow())
            return;
//        requestLayout(); TODO 未找到对应
        postLayout();
        updateBackgroundBitmap();
        invalidate();
    }


    public enum Orientation {
        HORIZONTAL, VERTICAL
    }
}
